package com.zndroid.netmonitor.monitor;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.zndroid.netmonitor.NetType;

public class Util {
    /**
     * 判断网络是否可用
     *
     * @return true/false
     */
    @SuppressLint("MissingPermission")
    public boolean isNetworkAvailable(@NonNull Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm != null) {
            if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                NetworkInfo mWiFiNetworkInfo = cm.getActiveNetworkInfo();
                if (mWiFiNetworkInfo != null) {
                    if (mWiFiNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI) //WIFI
                        return true;
                    else if (mWiFiNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE) //移动数据
                        return true;
                }
            } else {
                Network network = cm.getActiveNetwork();
                if (network != null) {
                    NetworkCapabilities nc = cm.getNetworkCapabilities(network);
                    if (nc != null) {
                        //移动数据
                        if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) //WIFI
                            return true;
                        else
                            return nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
                    }
                }
            }
        }

        return false;
    }


    /**
     * 判断是否包含SIM卡
     *
     * @return 状态
     */
    public boolean hasSimCard(@NonNull Context context) {
        TelephonyManager telMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        int simState = telMgr.getSimState();
        boolean result = true;
        switch (simState) {
            case TelephonyManager.SIM_STATE_ABSENT:
            case TelephonyManager.SIM_STATE_UNKNOWN:
            case TelephonyManager.SIM_STATE_CARD_IO_ERROR:
            case TelephonyManager.SIM_STATE_CARD_RESTRICTED:
            case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
            case TelephonyManager.SIM_STATE_NOT_READY:
            case TelephonyManager.SIM_STATE_PERM_DISABLED:
            case TelephonyManager.SIM_STATE_PIN_REQUIRED:
            case TelephonyManager.SIM_STATE_PUK_REQUIRED:
                result = false;
                break;
            case TelephonyManager.SIM_STATE_READY:
                break;
            default:
                result = true;
                break;
        }

        return result;
    }

    public boolean isWifiConnected(@NonNull Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mWiFiNetworkInfo = mConnectivityManager
                    .getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            if (mWiFiNetworkInfo != null) {
                return mWiFiNetworkInfo.isConnected();
            }
        }
        return false;
    }

    public boolean isMobileConnected(@NonNull Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mMobileNetworkInfo = mConnectivityManager
                    .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
            if (mMobileNetworkInfo != null) {
                return mMobileNetworkInfo.isConnected();
            }
        }
        return false;
    }

    /**
     * 检查当前连接的网络是否为5G WI-FI
     */
    private boolean is5GWifi(@NonNull Context context) {
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        if (wifiInfo == null) return false;
        // 频段
        int frequency = 0;
        if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.LOLLIPOP) {
            frequency = wifiInfo.getFrequency();
        } else {
            String ssid = wifiInfo.getSSID();
            if (TextUtils.isEmpty(ssid)) return false;
            if (ssid.length() < 2) return false;
            String sid = ssid.substring(1, ssid.length() -1);
            for (ScanResult result : wifiManager.getScanResults()) {
                if (result.SSID.equalsIgnoreCase(sid)) {
                    frequency = result.frequency;
                    break;
                }
            }
        }
        return frequency >=4900 && frequency <= 5900;
    }

    /**
     * 获取当前连接Wi-Fi名
     * # 如果没有定位权限，获取到的名字将为  unknown ssid
     */
    private String getConnectedWifiSSID(@NonNull Context context){
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        if (wifiInfo == null) return "";

        return wifiInfo.getSSID().substring(1, wifiInfo.getSSID().length() -1);
    }

    /**
     * 获取网络状态
     *
     * GPRS    2G(2.5) General Packet Radia Service 114kbps
     * EDGE    2G(2.75G) Enhanced Data Rate for GSM Evolution 384kbps
     * UMTS    3G WCDMA 联通3G Universal MOBILE Telecommunication System 完整的3G移动通信技术标准
     * CDMA    2G 电信 Code Division Multiple Access 码分多址
     * EVDO_0  3G (EVDO 全程 CDMA2000 1xEV-DO) Evolution - Data Only (Data Optimized) 153.6kps - 2.4mbps 属于3G
     * EVDO_A  3G 1.8mbps - 3.1mbps 属于3G过渡，3.5G
     * 1xRTT   2G CDMA2000 1xRTT (RTT - 无线电传输技术) 144kbps 2G的过渡,
     * HSDPA   3.5G 高速下行分组接入 3.5G WCDMA High Speed Downlink Packet Access 14.4mbps
     * HSUPA   3.5G High Speed Uplink Packet Access 高速上行链路分组接入 1.4 - 5.8 mbps
     * HSPA    3G (分HSDPA,HSUPA) High Speed Packet Access
     * IDEN    2G Integrated Dispatch Enhanced Networks 集成数字增强型网络 （属于2G，来自维基百科）
     * EVDO_B  3G EV-DO Rev.B 14.7Mbps 下行 3.5G
     * LTE     4G Long Term Evolution FDD-LTE 和 TDD-LTE , 3G过渡，升级版 LTE Advanced 才是4G
     * EHRPD   3G CDMA2000向LTE 4G的中间产物 Evolved High Rate Packet Data HRPD的升级
     * HSPAP   3G HSPAP 比 HSDPA 快些
     *
     * @return NetType as String
     */
    public @NetType String getNetType(@NonNull Context context) {
        ConnectivityManager manager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        if (null == manager) return NetType.NET_NONE;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Network net = manager.getActiveNetwork();
            if (net == null) return NetType.NET_NONE;

            NetworkCapabilities capabilities = manager.getNetworkCapabilities(net);
            if (capabilities == null) return NetType.NET_NONE;

            return getNetType(context, capabilities);
        } else {
            NetworkInfo activeNetworkInfo = manager.getActiveNetworkInfo();
            if (activeNetworkInfo == null || !activeNetworkInfo.isAvailable()) {
                return NetType.NET_NONE;
            }

            if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI)
                return NetType.NET_WIFI;
            else if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                NetworkInfo networkInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
                if (null != networkInfo) {
                    return subCellularType(context, networkInfo);
                } else
                    return NetType.NET_NONE;
            }
        }

        return NetType.NET_UNKNOWN;
    }

    @SuppressLint("MissingPermission")
    private @NetType String subCellularType(@NonNull Context context, @NonNull NetworkInfo networkInfo) {
        TelephonyManager telephonyManager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
        int subType;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            subType = telephonyManager.getDataNetworkType();
        } else {
            subType = networkInfo.getSubtype();
        }

        NetworkInfo.State state = networkInfo.getState();
        String subTypeName = networkInfo.getSubtypeName();
        if (state == NetworkInfo.State.CONNECTED
                || state == NetworkInfo.State.CONNECTING) {
            switch (subType) {
                //2G
                case TelephonyManager.NETWORK_TYPE_GPRS: // 联通2g
                case TelephonyManager.NETWORK_TYPE_CDMA: // 电信2g
                case TelephonyManager.NETWORK_TYPE_EDGE: // 移动2g
                case TelephonyManager.NETWORK_TYPE_1xRTT:
                case TelephonyManager.NETWORK_TYPE_IDEN:
                case TelephonyManager.NETWORK_TYPE_GSM:
                    return NetType.NET_2G;
                //3G
                case TelephonyManager.NETWORK_TYPE_EVDO_A: // 电信3g
                case TelephonyManager.NETWORK_TYPE_UMTS:
                case TelephonyManager.NETWORK_TYPE_EVDO_0:
                case TelephonyManager.NETWORK_TYPE_HSDPA:
                case TelephonyManager.NETWORK_TYPE_HSUPA:
                case TelephonyManager.NETWORK_TYPE_HSPA:
                case TelephonyManager.NETWORK_TYPE_EVDO_B:
                case TelephonyManager.NETWORK_TYPE_EHRPD:
                case TelephonyManager.NETWORK_TYPE_HSPAP:
                case TelephonyManager.NETWORK_TYPE_IWLAN:
                    return NetType.NET_3G;
                //4G
                case TelephonyManager.NETWORK_TYPE_LTE:
                    return NetType.NET_4G;
                //5G
                case TelephonyManager.NETWORK_TYPE_NR:
                    return NetType.NET_5G;
                default:
                    //中国移动 联通 电信 三种3G制式
                    if (subTypeName.equalsIgnoreCase("TD-SCDMA")
                            || subTypeName.equalsIgnoreCase("WCDMA")
                            || subTypeName.equalsIgnoreCase("CDMA2000")) {
                        return NetType.NET_3G;
                    } else {
                        return NetType.NET_CELLULAR;
                    }
            }
        } else if (state == NetworkInfo.State.DISCONNECTED
                || state == NetworkInfo.State.DISCONNECTING) {
            return NetType.NET_NONE;
        } else
            return NetType.NET_UNKNOWN;
    }

    /**
     * 获取网络状态
     */
    public @NetType String getNetType(@NonNull Context context, NetworkCapabilities capabilities) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                    || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE))
                return NetType.NET_WIFI;

            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                    || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
                //NetType.NET_CELLULAR;
                ConnectivityManager manager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo networkInfo = manager.getActiveNetworkInfo();
                return subCellularType(context, networkInfo);
            }

            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN))
                return NetType.NET_VPN;

            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH))
                return NetType.NET_BLUETOOTH;

            if (!capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED))
                return NetType.NET_NONE;
        }

        return NetType.NET_UNKNOWN;
    }
}
